package com.newtribe.tk;

import java.util.HashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * <p> </p>
 * <p>Description: Innovatation method</p>
 * <p>Copyright: Copyright (c)  newtribe innovation 2005</p>
 * <p> the abstract Task executer . </p>
 * @author fuwei
 * @version 1.0
 */

public  abstract class TKWorker implements Runnable{

  // logging instance .
  public Log log = LogFactory.getLog(TKWorker.class) ;
  //thread name
  private String name =null ;
  //ThreadPool the current TKWorker belongs
  private ThreadPool threadPool =null ;

  private Task task =null ; //the needed process task object .

  //specified whether the current thread state .
  private boolean stop = false;

  private long start ,end  ; //worker start execute task time and finished task time .

  public TKWorker() {
    this("worker"+System.currentTimeMillis()) ;
  }
  public TKWorker(String name ) {
    setName(name) ;

  }
  public void setName(String name ) {
    this.name =name ;
  }
  //set the current worker belongs .
  public void setParent(ThreadPool pool) {
    this.threadPool =pool ;
  }
  public static void main(String[] args) {
    TKWorker TKWorker1 = null ;
    boolean s= ( TKWorker1 instanceof java.io.Serializable );

  }

  /**
   * dispatch the task needed to been executed .
   * this method delegated to synchronzied assignTask method
   * @param task
   */
 public void dispatch(Task task) {
   assignTask(task) ;
 }

   synchronized void assignTask(Task task) {

     if(this.task !=null) {
       //log.fatal("log fatal ..............");
       throw new IllegalStateException("the previous task is running!") ;

     }
     this.task =task ;
      notifyAll() ;
   }
   /**
    * execute main loop process logic .
    * @throws java.lang.Exception
    */
   protected void mainLoop() throws Exception {

     while (!checkStop()) {

       ready(); //wait execute  task notify
       if (this.task != null)
         try {
         //performance test
          start =System.currentTimeMillis() ;

          //do process
          processTask(this.task) ;

          //end do
           end =System.currentTimeMillis() ;
           double used =(end -start) /1000 ;
         // log.info(Thread.currentThread().getName()+"execute cost seconds:" +used ) ;
           //end performance test
         }
         catch (Throwable e) {
           e.printStackTrace();
         }
       finally {
         // log.info(Thread.currentThread() .getName() +" return back to pool") ;
         this.task = null;
         if (threadPool !=null)
         threadPool.recycle(this); //�Żس���.



       }

     }
   }

   abstract public void  processTask(Task task ) throws Exception  ;

   private synchronized void ready() {

	  log.info(Thread.currentThread().getName() + " wait execute task notify ...");

     while ( !checkStop() && this.task == null) {
       try {
         wait(1000);
       }
       catch (Exception e) {
         log.error("wait interrupt:" ,e);
       }
     }
   }

    public boolean checkStop() {
      return this.stop;
    }



   public void start() {
     //init url queue buffer .

     Thread t = new Thread(this ,name);

     t.setPriority(Thread.MIN_PRIORITY);
     t.start();

   }

   public  void stop() {

     stop = true;
     synchronized (this) {
       this.notifyAll() ;
     }

   }
   public final void run() {
   //  log.info(Thread.currentThread() .getName() +" started ...");
     try {
       //notify thread pool i am ready .
       if (this.threadPool !=null) {
    	   synchronized(this.threadPool) {
    	   this.threadPool.recycle(this);
    	   }
       
       }
       mainLoop();
       log.info(Thread.currentThread() .getName() +" stoped ...");
     }
     catch (Throwable t) { //un expected error occrued .
       log.fatal("thread interrupt by uncatched error:" ,t);
     }finally {

     }
   }

}